package com.dingding.service.usermangerservice.impl;

import java.util.Date;

import javax.annotation.Resource;

import org.apache.log4j.Logger;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.Restrictions;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.dingding.bean.databean.request.ReqGetTellPhoneValidate;
import com.dingding.bean.databean.request.ReqValidateTellPhoneNum;
import com.dingding.bean.databean.response.DataResponse;
import com.dingding.bean.entity.Phonevalidate;
import com.dingding.bean.entity.UserLogin;
import com.dingding.common.core.config.ServiceCode;
import com.dingding.common.core.config.SystemCode;
import com.dingding.common.core.util.JSONUtil;
import com.dingding.common.core.util.ToolUtil;
import com.dingding.facade.queue.dto.msg.MessageRequestsDTO;
import com.dingding.facade.queue.facade.IQueueFacade;
import com.dingding.message.MessageModel;
import com.dingding.service.BaseService;
import com.dingding.service.usermangerservice.IPhoneValidateService;

/**
 * 
 * @ClassName: PhoneValidateServiceImpl
 * @Description:手机验证码服务类
 * @author fengshuonan
 * @date 2015-10-20 上午09:56:57
 * @version 叮叮搭车2.0
 */
public class PhoneValidateServiceImpl extends BaseService implements IPhoneValidateService {

	private Logger log = Logger.getLogger(this.getClass());
	
	// 验证码剩余次数(连续失败五次，则当天不能进行验证)
	private Integer validateFailNumber = 0;
	
	@Resource(name = "queueFacade")
	private IQueueFacade queuefacade;


	/**
	 * @Title: addValidateNum
	 * @Description: 获取手机验证码
	 * @param phoneNum
	 *            请求bean
	 * @param dataResponse
	 *            服务器数据响应封装bean
	 * @author fengshuonan
	 */
	@Transactional(propagation = Propagation.REQUIRED, rollbackFor = RuntimeException.class)
	public void getTellPhoneValidate(ReqGetTellPhoneValidate reqGetTellPhoneValidate, DataResponse dataResponse) {

		// 判断客户端请求参数是否为空
		boolean isTrue = this.isGetTelNoValidateParamTrue(reqGetTellPhoneValidate);

		// 请求数据是否为空
		if (!isTrue) {
			log.error("获取手机验证码参数为空:" + reqGetTellPhoneValidate.toString());
			setStatus(dataResponse, SystemCode.DATA_NULL_ERROR);
			return;
		}

		// 手机号码格式不正确
		if (!reqGetTellPhoneValidate.getPhoneNum().matches(ServiceCode.PHONE_NUM_CODE)) {
			setStatus(dataResponse, SystemCode.PHONE_NUM_NOT_MATCH_ERROR);
			return;
		}

		// 获取手机号
		String phoneNum = reqGetTellPhoneValidate.getPhoneNum();

		// 设置验证码创建时间
		Date date = new Date();

		// 生成4位随机数
		String validateNum = ToolUtil.generateCellPhoneValNum();

		Phonevalidate phonevalidate = null;

		// 创建短信内容
		String msg = null;

		// 注册
		UserLogin userlogin = null;
		// 根据电话号码创建查询条件
		Criterion userLoginCriterion = Restrictions.eq("userName", reqGetTellPhoneValidate.getPhoneNum());

		try {

			// 查看数据库是否存在此电话号码
			userlogin = super.userLoginDao.queryCriteriaUnResult(userLoginCriterion, false);

		} catch (Exception e) {
			log.error("根据电话号码查询用户信息出现异常！类：" + this.getClass() + " getTellPhoneValidate()", e);
			setStatus(dataResponse, SystemCode.ERROR);
			return;
		}

		if (reqGetTellPhoneValidate.getValidateType() == 1) {// 登录时获取短信验证码

			// 注册时要发送的短信内容
			msg = MessageModel.registered(validateNum);

		} else if (reqGetTellPhoneValidate.getValidateType() == 2) {// 首次提现时获取短信验证码

			// 如果不存在该用户
			if (userlogin == null) {
				// 找回密码时该用户不存在,终止获取手机验证码
				setStatus(dataResponse, SystemCode.USER_INFO_NOT_EXIST_ERROR);
				return;
			}

			// 找回密码时要发送的短信内容
			msg = MessageModel.backPwd(validateNum);
		}

		// 根据手机验证码创建查询条件
		Criterion phoneValidateCriterion = Restrictions.eq("phoneNum", phoneNum);

		try {

			// 查看数据库是否存在此手机号码
			phonevalidate = super.phoneValidateDao.queryCriteriaUnResult(phoneValidateCriterion, false);

		} catch (Exception e) {

			log.error("查询手机号码出错！PhoneValidateServiceImpl ：getTellPhoneValidate", e);

			// 返回错误状态码
			setStatus(dataResponse, SystemCode.ERROR);
			return;
		}

		// 如果数据库不存在这个电话号码记录
		if (phonevalidate == null) {

			// 初始化bean
			phonevalidate = new Phonevalidate();
			// 设置主键id
			phonevalidate.setVid(ToolUtil.getUid());
			// 设置手机号码
			phonevalidate.setPhoneNum(phoneNum);
			// 设置验证码
			phonevalidate.setValidateNum(validateNum);
			// 设置过期时间
			phonevalidate.setCreateTime(date);
			// 验证码连续输错次数
			phonevalidate.setValidateCodeNumber(0);
			// 是否有效(1:有效 2:无效)
			phonevalidate.setIsValid(1);

			// 将手机号和验证码保存到数据库
			super.phoneValidateDao.save(phonevalidate);

		} else { // 如果数据库有这个电话号码记录

			// 验证失败累计次数
			if (phonevalidate.getValidateCodeNumber() == null) {
				phonevalidate.setValidateCodeNumber(0);
			}

			if (phonevalidate.getValidateCodeNumber() >= 5) {

				// 验证码可用的验证次数
				validateFailNumber = 5 - phonevalidate.getValidateCodeNumber();

				// 本日验证码已累计输入错误五次
				setStatus(dataResponse, SystemCode.VALIDATE_NOT_THROUGH_ERROR);
				return;
			}

			// 设置验证码
			phonevalidate.setValidateNum(validateNum);
			// 设置过期时间
			phonevalidate.setCreateTime(date);
			// 是否有效
			phonevalidate.setIsValid(1);

		}
		//添加到消息队列
		MessageRequestsDTO messageRequestsDTO = new MessageRequestsDTO();
		messageRequestsDTO.setTelPhone(reqGetTellPhoneValidate.getPhoneNum());
		messageRequestsDTO.setMessageContent(msg);
		boolean flag = queuefacade.addMessageToQueue(JSONUtil.toJSONString(messageRequestsDTO));

		// 如果发送成功
		if (flag) {
			// 返回成功响应码
			setStatus(dataResponse, SystemCode.SUCCESS);
			return;
		} else {
			log.error("发送短信验证码失败! PhoneValidateServiceImpl:getTellPhoneValidate()");
			// 返回失败响应码
			setStatus(dataResponse, SystemCode.ERROR);
			return;
		}

	}

	/**
	 * 
	 * @Title: validateTellPhoneNum
	 * @Description:手机验证码校验
	 * @param validateTellPhoneNum
	 *            请求的手机号
	 * @param dataResponse
	 *            响应客户端的状态码信息
	 * @author fengshuonan
	 * @throws
	 * @Override
	 */
	@Transactional(propagation = Propagation.REQUIRED)
	public void validateTellPhoneNum(ReqValidateTellPhoneNum validateTellPhoneNum, DataResponse dataResponse) {

		// 验证手机验证码校验时传入的参数是否为空
		boolean isTrue = this.isValidateTellPhoneNumParamTrue(validateTellPhoneNum);

		// 判断请求参数是否为空
		if (!isTrue) {
			// 返回请求数据为空状态码
			log.error("验证手机验证码请求参数为空:" + validateTellPhoneNum.toString());
			setStatus(dataResponse, SystemCode.DATA_NULL_ERROR);
			return;
		}

		// 获取手机号码
		String phoneNum = validateTellPhoneNum.getPhoneNum();
		// 获取验证码
		String validateNum = validateTellPhoneNum.getValidateNum();

		// 创建手机验证码对象
		Phonevalidate phonevalidate = null;
		// 根据手机号和验证码添加条件
		Criterion criterion = Restrictions.and(Restrictions.eq("phoneNum", phoneNum));
		try {

			// 根据手机号和验证码获取手机验证码对象
			phonevalidate = super.phoneValidateDao.queryCriteriaUnResult(criterion, false);

		} catch (Exception e) {

			log.error("手机验证码校验出错！PhoneValidateServiceImpl:validateTellPhoneNum()", e);

			// 返回错误状态码
			setStatus(dataResponse, SystemCode.ERROR);
			return;
		}

		// 如果获取的手机验证码对象不为空
		if (phonevalidate != null) {

			// 判断手机验证码是否输入正确
			if (!phonevalidate.getValidateCodeNumber().equals(validateNum)) {
				// 返回 验证码错误 状态码
				phonevalidate.setValidateCodeNumber(phonevalidate.getValidateCodeNumber() + 1);
				setStatus(dataResponse, SystemCode.VALIDATE_NOT_THROUGH_ERROR);
				return;
			}

			// 如果没有过期
			if (ToolUtil.validateTimeOut(phonevalidate.getCreateTime()) == true && phonevalidate.getIsValid() == 1) {
				// 返回 成功 状态码
				setStatus(dataResponse, SystemCode.SUCCESS);
				phonevalidate.setIsValid(2);
				return;
			} else {
				// 返回 验证码过期 状态码
				setStatus(dataResponse, SystemCode.VALIDATE_THROUGH_ERROR);
				return;
			}
		}
		// 返回错误状态码
		setStatus(dataResponse, SystemCode.ERROR);
		return;
	}

	/**
	 * @Title: getTelNoValidateParam
	 * @Description: 获取验证码校验参数
	 * @param reqGetTellPhoneValidate
	 * @author lijinchao
	 * @return true 参数正确  false 参数不正确
	 * @throws
	 */
	private boolean isGetTelNoValidateParamTrue(ReqGetTellPhoneValidate reqGetTellPhoneValidate) {

		if (reqGetTellPhoneValidate == null) {
			return false;
		}
		// 手机号
		if (ToolUtil.isBlank(reqGetTellPhoneValidate.getPhoneNum())) {
			return false;
		}
		// 验证码类型
		if (reqGetTellPhoneValidate.getValidateType() == null) {
			return false;
		}

		return true;
	}

	/**
	 * @Title: validateTellPhoneNumParam
	 * @Description:手机验证码校验-客户端传入参数是否为空
	 * @param validateTellPhoneNum
	 *            请求的手机号
	 * @author yhq
	 * @return true 参数正确  false 参数不正确
	 * @Override
	 */
	private boolean isValidateTellPhoneNumParamTrue(ReqValidateTellPhoneNum validateTellPhoneNum) {

		if (validateTellPhoneNum == null) { // 验证码是否为空
			return false;
		}
		// 验证手机号
		if (ToolUtil.isBlank(validateTellPhoneNum.getPhoneNum())) {
			return false;
		}
		// 验证码
		if (ToolUtil.isBlank(validateTellPhoneNum.getValidateNum())) {
			return false;
		}

		return true;
	}

	/**
	 * 
	 * @Title: setStatus
	 * @Description:根据状态码设置响应信息
	 * @param dataResponse
	 *            响应信息封装bean
	 * @param status
	 *            状态码
	 * @author fengshuonan
	 * @return void
	 * @throws
	 */
	public void setStatus(DataResponse dataResponse, int status) {
		String message = null;
		switch (status) {
		case SystemCode.SUCCESS:// 请求成功
			message = SystemCode.SUCCESS_MESSAGE;
			break;
		case SystemCode.VALIDATE_THROUGH_ERROR:// 手机验证码失效
			message = SystemCode.VALIDATE_THROUGH_MESSAGE;
			break;
		case SystemCode.VALIDATE_NOT_THROUGH_ERROR:// 验证码输入不正确
			message = SystemCode.VALIDATE_NOT_THROUGH_MESSAGE(validateFailNumber);
			break;
		case SystemCode.ERROR:// 系统异常
			message = SystemCode.ERROR_MESSAGE;
			break;
		case SystemCode.DATA_NULL_ERROR:// 客户端请求数据为空
			message = SystemCode.DATA_NULL_MESSAGE;
			break;
		case SystemCode.DATA_NULL_PARAM:// 客户端请求参数为空
			message = SystemCode.DATA_NULL_PARAM_MESSAGE;
			break;
		case SystemCode.REGISTER_USER_EXIST_ERROR:// 用户已存在
			message = SystemCode.REGISTER_USER_EXIST_MESSAGE;
			break;
		case SystemCode.USER_INFO_NOT_EXIST_ERROR:// 用户不存在
			message = SystemCode.USER_INFO_NOT_EXIST_MESSAGE;
			break;
		case SystemCode.PHONE_NUM_NOT_MATCH_ERROR:// 手机格式不正确
			message = SystemCode.PHONE_NUM_NOT_MATCH_MESSAGE;
			break;
		}

		dataResponse.setResponseCode(status);
		dataResponse.setResponseMessage(message);
	}

}
